/* eslint-disable no-param-reassign */
import { useEffect, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { Transfer } from 'antd';
import difference from 'lodash/difference';
import throttle from 'lodash/throttle';

import ProTable from '@/components/ProTable';

const TableTransfer = ({
  leftColumns,
  rightColumns,
  pagination,
  setPagination,
  coverageData,
  curRight,
  request,
  isSearch,
  copyRightData,
  ...restProps
}) => (
  <Transfer {...restProps}>
    {({
      direction,
      onItemSelectAll,
      onItemSelect,
      selectedKeys: listSelectedKeys,
      disabled: listDisabled,
    }) => {
      const columns = direction === 'left' ? leftColumns : rightColumns;

      const rowSelection = {
        getCheckboxProps: (item) => ({
          disabled: listDisabled || item.disabled,
        }),
        onSelectAll(selected, selectedRows) {
          const treeSelectedKeys = selectedRows
            .filter((item) => !item.disabled)
            .map(({ key }) => key);
          const diffKeys = selected
            ? difference(treeSelectedKeys, listSelectedKeys)
            : difference(listSelectedKeys, treeSelectedKeys);
          onItemSelectAll(diffKeys, selected);
        },
        onSelect({ key }, selected) {
          onItemSelect(key, selected);
        },
        selectedRowKeys: listSelectedKeys,
      };

      const handleTableChange = (p) => {
        request(p);
        if (direction === 'left') {
          setPagination(p);
        }
      };

      return (
        <ProTable
          scroll={{
            y: 400,
          }}
          rowSelection={rowSelection}
          pagination={direction === 'left' ? pagination : false}
          columns={columns}
          dataSource={
            direction === 'left'
              ? coverageData
              : isSearch.current
              ? copyRightData
              : curRight.current
          }
          size="small"
          style={{ pointerEvents: listDisabled ? 'none' : null }}
          onRow={({ key, disabled: itemDisabled }) => ({
            onClick: () => {
              if (itemDisabled || listDisabled) return;
              onItemSelect(key, !listSelectedKeys.includes(key));
            },
          })}
          onChange={handleTableChange}
          search={false}
          options={false}
        />
      );
    }}
  </Transfer>
);

const WithCoverage = ({ id, onChange }) => {
  const dispatch = useDispatch();
  const [targetKeys, setTargetKeys] = useState([]);
  const [searchValue, setSearchValue] = useState('');
  const [coverageData, setCoverageData] = useState([]);
  const [selectedKeys, setSelectedKeys] = useState([]);
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: 100,
    pageSizeOptions: [100],
  });
  const [rightSearchValue, setRightSearchValue] = useState('');
  const [copyRightData, setCopyRightData] = useState([]);
  const curRight = useRef([]);
  // const copyRightData = useRef([])
  const isSearch = useRef(false);
  const needDelete = useRef([]);
  const num = useRef(0);

  const request = throttle((pagination) => {
    dispatch({
      type: 'label/loadTagWithCoverage',
      payload: {
        tagId: id,
        page: pagination.current,
        value: searchValue,
        callback: (data, total) => {
          setPagination({ ...pagination, total });
          data = data.filter((item) => !needDelete.current.includes(item.key));
          setCoverageData(
            data?.map((item) => {
              if (targetKeys.includes(item.id)) {
                item.disabled = true;
                item.key = num.current++;
                needDelete.current.push(item.key);
              } else {
                item.key = item.id;
              }
              return item;
            }),
          );
        },
      },
    });
  }, 2000);

  useEffect(() => {
    request(pagination);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchValue]);

  const copyRightDataFn = (value) => {
    setCopyRightData(
      curRight.current.filter((item) => item.value.includes(value)),
    );
    isSearch.current = true;
  };

  const change = (nextTargetKeys, direction, moveKeys) => {
    if (direction === 'right') {
      isSearch.current = false;
      const screen = coverageData
        .filter((item) => moveKeys.includes(item.key))
        .map((ele) => ({ ...ele }));
      curRight.current =
        curRight.current.length > 0 ? curRight.current.concat(screen) : screen;
      // copyRightData.current = curRight.current

      setCoverageData(
        coverageData.map((ele) => {
          if (nextTargetKeys.includes(ele.id)) {
            ele.disabled = true;
            ele.key = num.current;
            num.current++;
            ele = { ...ele };
          }
          return ele;
        }),
      );
    } else {
      const map = new Map();
      curRight.current
        .filter((ele) => moveKeys.includes(ele.key))
        .forEach((ele) => {
          map.set(ele.id, ele);
        });
      // copyRightData.current = curRight.current

      setCoverageData(
        coverageData.map((item) => {
          if (map.has(item.id)) {
            return map.get(item.id);
          }
          return item;
        }),
      );

      curRight.current = curRight.current.filter(
        (item) => !moveKeys.includes(item.id),
      );
      copyRightDataFn(rightSearchValue);

      // copyRightData.current = curRight.current
      // setCoverageData(coverageData.map(item => !item.disabled))
    }
    setTargetKeys(nextTargetKeys);
    onChange(
      curRight.current.map((item) => ({
        tagDataId: item.id,
        value: item.value,
      })),
    );
  };

  const onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
    setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
  };

  const columns = [
    {
      dataIndex: 'value',
      title: '用户名',
    },
    {
      dataIndex: 'coverage',
      title: '粉丝数',
    },
  ];

  const onSearch = (direction, value) => {
    if (direction === 'left') {
      setSearchValue(value);
    } else {
      copyRightDataFn(value);
      setRightSearchValue(value);
    }
  };

  const filterOption = () => {
    return true;
  };

  return (
    <TableTransfer
      dataSource={coverageData}
      targetKeys={targetKeys}
      selectedKeys={selectedKeys}
      leftColumns={columns}
      rightColumns={columns}
      onChange={change}
      onSelectChange={onSelectChange}
      showSearch
      onSearch={onSearch}
      filterOption={filterOption}
      pagination={pagination}
      showSelectAll={false}
      setPagination={setPagination}
      style={{ width: '100%' }}
      setCoverageData={setCoverageData}
      coverageData={coverageData}
      curRight={curRight}
      request={request}
      copyRightData={copyRightData}
      isSearch={isSearch}
    />
  );
};

export default WithCoverage;
